k8sの基本を学ぶ


概要

必要が出たので学ぶ。



k8sについて

適当に平易な言葉を使って表現すると、

・クラスタリングしたコンテナのコントロールを行うコマンドラインツール

kubectl コマンドにいろいろなオプションをつけるとコンテナ群をいい感じに管理してくれる。



いろいろな用語


MasterとNode

Masterが総合的なサービスのコントローラ、Nodeがコンテナの実行部分。



Resource

k8sにはいろいろな要素グループがあり、総称はResource


Resourceという要素の中に、Pod、Node、Masterなどがある。

全ての要素にlabelをつけることができる。

namespaceという単位で括ることができる。何も指定しない場合default。


Pod

1つ以上のコンテナが入ったResource。

k8sではこの単位でアプリケーションを運用する。

この単位でNodeにデプロイされる。


Service

Resourceへのインターフェースを提供するResource

labelでPodを判別し、インターフェースを提供する。



ReplicaSet

Podの調整を行う関数みたいなResource。

labelに則ってPodを検索し、指定した数値と見つかったPodの多寡で調整を行う。


Deployment

アプリケーションのアップデートやロールバックを宣言的に行うためのResource。



とりあえず基礎はこんなところか。



minukubeを使ってうごかしてみる

依存

mac用だとhyperkitとかに依存してる。で、これはdocker入れたら入ってるっぽいんだよな。

-> dockerが持ってるHyperkitとの橋渡しのドライバがあるみたいだ。下記で入れる。

curl -LO https://storage.googleapis.com/minikube/releases/latest/docker-machine-driver-hyperkit \

&& chmod +x docker-machine-driver-hyperkit \

&& sudo mv docker-machine-driver-hyperkit /usr/local/bin/ \

&& sudo chown root:wheel /usr/local/bin/docker-machine-driver-hyperkit \

&& sudo chmod u+s /usr/local/bin/docker-machine-driver-hyperkit



minikubeのインストール

curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.25.0/minikube-darwin-amd64

これ以外のバージョンだと動作しなかった。こえーー。


具体的にいうと、kubectl 1.9.0とminikube 0.25.0の組み合わせ以外で動かなかった。



起動

minikube start --vm-driver=hyperkit


パラメータはconfigでセットしておくことができる。

minikube config set vm-driver hyperkit



状態

minikube status

minikube: Running

cluster: Running

kubectl: Correctly Configured: pointing to minikube-vm at 192.168.64.6



imageのデプロイと実行

kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.4 --port=8080

imageとportを指定して投入する。

この時点でport 8080にアクセスしても何も起こらない。


投入されたコンテナはpodに入る = podが生成される。

kubectl get pod

NAME                            READY     STATUS    RESTARTS   AGE

hello-minikube-c6c6764d-f8nhg   1/1       Running   0          5m

ラベル付きのものを取得したい場合、-l k=v とかやると抽出できる。



実行するとdeploymentが生成されているので、検知できるようになる。

kubectl get deployment

NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE

hello-minikube   1         1         1            1           9m



deploymentについての記述を見てみる。

kubectl describe deployment hello-minikube


これで元になっているimageとか空いてるポートとかが確認できる。



deploymentへと接続するhello-minikubeというサービスを生成

kubectl expose deployment hello-minikube --type=NodePort



hello-minikube サービスのurlを取得(urlオプション無しだと自動的にブラウザで開く)

minikube service hello-minikube --url



削除、deploymentとserviceを消す。

kubectl delete deployment hello-minikube

kubectl delete service hello-minikube


概念的には、


1.runでpodがデプロイされ、指定した名前のdeploymentリソースが生成される。

2.生成されたdeploymentに対して、expose 名前指定 + 接続オプションで、外部からアクセス可能なipとポートが生成される。

という感じで、デプロイ -> サービス生成 という手順を踏むと公開される。


接続オプションにはNodePortとLoadBalancer、Ingress がある。

minikubeで使えるのはNodePortのみ。実際にはLBかIngressを使うっぽい。



ファイルをもとにdeployを行う

yamlの視認性はヤバいのでjsonで。


dep.json

{

   "apiVersion": "apps/v1",

   "kind": "Deployment",

   "metadata": {// デプロイ自体の設定

      "name": "nginx-hostname-deployment",

      "labels": {

         "app": "nginx-hostname"

      }

   },

   "spec": {// replicaとかtemplate、selectorが所属する属性。

      "replicas": 1,

      "selector": {

         "matchLabels": {

            "app": "nginx-hostname"

         }

      },

      "template": {

         "metadata": {

            "labels": {

               "app": "nginx-hostname"

            }

         },

         "spec": {

            "containers": [

               {

                  "name": "nginx-hostname",// 名前

                  "image": "stenote/nginx-hostname",// 元にするイメージ

                  "ports": [// exposeするポート

                     {

                        "containerPort": 80

                     }

                  ]

               }

            ]

         }

      }

   }

}


これを実行する。

kubectl apply -f dep.json


すると、nginx-hostname-deploymentというdeploymentが作成される。


podとreplicaSetについて指定してあり、それらが生成されている。

その状態はkubectl get pod -l app=nginx-hostname とかで取得できる。

deplpyment name指定でserviceを作成、公開状態にする。

kubectl expose deployment nginx-hostname-deployment ---type=NodePort


で、公開済みのserviceの情報を見るには下記が使える。

kubectl get service nginx-hostname-deployment

kubectl describe service nginx-hostname-deployment


ここから、このセットをスケールアウトさせてみる。

kubectl scale --replicas=5 deployment nginx-hostname-deployment

これで5つまでスケールする。(ここではオフラインで実行したんで失敗してる。)

kubectl get pod -l app=nginx-hostname

NAME                                        READY     STATUS             RESTARTS   AGE

nginx-hostname-deployment-8b65c84d7-6qzjj   1/1       Running            0          1h

nginx-hostname-deployment-8b65c84d7-77mv7   0/1       ErrImagePull       0          54m

nginx-hostname-deployment-8b65c84d7-7996w   0/1       ImagePullBackOff   0          54m

nginx-hostname-deployment-8b65c84d7-smc4w   0/1       ErrImagePull       0          54m

nginx-hostname-deployment-8b65c84d7-vlhkb   0/1       ErrImagePull       0          54m


scaleやりなおしてもimagePullBackOffから帰って来なかったやつが一機あったのが気になる、、、、



ということで、scaleコマンドでスケーリングできる。もちろんこれは減らす方向にも向かえる。


整理すると、

1.deploymentの設定ファイル書く

2.実行するとデプロイが行われる。書かれているimageが使われる

3.sca;eコマンドでdeployment/設定名 でスケーリングできる


となる感じで、これは便利。



APIまとめ

デプロイする

kubectl apply -f dep.json



デプロイ済みのものを公開する

kubectl expose deployment デプロイ名 ---type=NodePort

-> 指定したdeploymentに対して同じ名前のserviceが生成される。

-> typeはいろいろある(minikubeではNodePortしか使えない)



公開したデプロイのurlを得る(ここだけminikube)

minikube service hello-minikube --url

serviceとdeploymentは独立しているため、deploymentを消してもserviceは影響を受けない(ルーティング的には影響を受けそうだが)



スケールさせる

kubectl scale --replicas=5 deployment デプロイ名



非公開にする

kubectl delete service サービス名



停止させる

kubectl delete deployment デプロイ名





今のところの所感

apply、run、scale、delete、get、set、expose、describeとかは動詞的、

pod、service(svc)、deploymentはリソースの指定のkind扱い、resourceのフィルタに使われている感じ。

さらに-lオプションでのラベルでのフィルタリングがある。